package com.fzhucc.modules.businessCard.service.impl;


import com.fzhucc.config.FileProperties;
import com.fzhucc.exception.BadRequestException;
import com.fzhucc.modules.businessCard.domain.BusinessCard;
import com.fzhucc.modules.businessCard.domain.BusinessCardPre;
import com.fzhucc.modules.businessCard.domain.dto.BusinessCardAddDto;
import com.fzhucc.modules.businessCard.domain.dto.BusinessCardDto;
import com.fzhucc.modules.businessCard.domain.dto.BusinessCardEditDto;
import com.fzhucc.modules.businessCard.domain.dto.BusinessCardQueryCriteria;
import com.fzhucc.modules.businessCard.repository.BusinessCardPreRepository;
import com.fzhucc.modules.businessCard.repository.BusinessCardRepository;
import com.fzhucc.modules.businessCard.repository.BusinessCardStatusRepository;
import com.fzhucc.modules.businessCard.service.BusinessCardService;
import com.fzhucc.modules.businessCard.service.mapstruct.BusinessCardMapper;
import com.fzhucc.modules.system.service.UserService;
import com.fzhucc.modules.system.service.dto.UserDto;
import com.fzhucc.utils.*;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * @author yyg
 * @description 服务实现
 * @date 2022-10-24
 **/
@Service
@RequiredArgsConstructor
public class BusinessCardServiceImpl implements BusinessCardService {

    private final BusinessCardStatusRepository businessCardStatusRepository;

    private final BusinessCardRepository businessCardRepository;

    private final BusinessCardPreRepository businessCardPreRepository;
    private final BusinessCardMapper businessCardMapper;

    private final UserService userService;

    private final FileProperties properties;

    private final WxClient wxClient;

    @Override
    public Map<String, Object> queryAll(BusinessCardQueryCriteria criteria, Pageable pageable) {
        Page<BusinessCard> page = businessCardRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return PageUtil.toPage(page.map(businessCardMapper::toDto));
    }

    @Override
    public List<BusinessCardDto> queryAll(BusinessCardQueryCriteria criteria) {
        return businessCardMapper.toDto(businessCardRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    public BusinessCardDto findById(Integer id) {
        BusinessCard businessCard = businessCardRepository.findById(id).orElseGet(BusinessCard::new);
        ValidationUtil.isNull(businessCard.getId(), "BusinessCard", "id", id);
        return businessCardMapper.toDto(businessCard);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessCardDto create(BusinessCardAddDto businessCardAddDto) {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("用户ID未找到");
        } else {
            BusinessCard businessCard = new BusinessCard();
            businessCard.setUserId(userId);
            businessCard.setName(businessCardAddDto.getName());
            businessCard.setAffiliatedTradeUnion(businessCardAddDto.getAffiliatedTradeUnion());
            businessCard.setPost(businessCardAddDto.getPost());
            businessCard.setAddress(businessCardAddDto.getAddress());
            businessCard.setPhone(businessCardAddDto.getPhone());
            businessCard.setDept(businessCardAddDto.getDept());
            businessCard.setSuperiorUnit(businessCardAddDto.getSuperiorUnit());
            return businessCardMapper.toDto(businessCardRepository.save(businessCard));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(BusinessCardEditDto resources) {
        BusinessCard businessCard = new BusinessCard();
        businessCard.setId(resources.getId());
        businessCard.setName(resources.getName());
        businessCard.setAddress(resources.getAddress());
        businessCard.setAffiliatedTradeUnion(resources.getAffiliatedTradeUnion());
        businessCard.setPhone(resources.getPhone());
        businessCard.setPost(resources.getPost());
        businessCard.setDept(resources.getDept());
        businessCard.setSuperiorUnit(resources.getSuperiorUnit());
        BusinessCard businessCard2 = businessCardRepository.findById(resources.getId()).orElseGet(BusinessCard::new);
        ValidationUtil.isNull(businessCard2.getId(), "BusinessCard", "id", businessCard.getId());
        businessCard2.copy(businessCard);
        businessCardRepository.save(businessCard2);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            businessCardRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<BusinessCardDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (BusinessCardDto businessCard : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("名片名称", businessCard.getName());
            map.put("用户", businessCard.getUser());
            map.put("所属工会", businessCard.getAffiliatedTradeUnion());
            map.put("职务", businessCard.getPost());
            map.put("地址", businessCard.getAddress());
            map.put("联系方式", businessCard.getPhone());
            map.put("头像", businessCard.getPhoto());
            map.put("部门", businessCard.getDept());
            map.put("上级部门", businessCard.getSuperiorUnit());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public Map<String, String> douploadpic(MultipartFile multipartFile, Integer id) {
        // 文件大小验证
        FileUtil.checkSize(properties.getAvatarMaxSize(), multipartFile.getSize());
        // 验证文件上传的格式
        String image = "gif jpg png jpeg";
        String fileType = FileUtil.getExtensionName(multipartFile.getOriginalFilename());
        if (fileType != null && !image.contains(fileType)) {
            throw new BadRequestException("文件格式错误！, 仅支持 " + image + " 格式");
        }
        Optional<BusinessCard> res = businessCardRepository.findById(id);
        if (res.isPresent()) {
            BusinessCard businessCard = res.orElseGet(() -> new BusinessCard());
            String oldPath = businessCard.getPhoto();
            File file = FileUtil.upload(multipartFile, properties.getBusinesscard());
            String path = Objects.requireNonNull(file).getPath();
            String[] files = path.split("file");
            res.get().setPhoto("/file" + files[1]);
            businessCardRepository.save(res.get());
            if (StringUtils.isNotBlank(oldPath)) {
                FileUtil.del(oldPath);
            }
            return new HashMap<String, String>(1) {{
                put("businesscard", file.getName());
            }};
        }
        return new HashMap<String, String>(1) {{
            put("businesscard", "fail");
        }};
    }

    @Override
    public String makeQRcode(Integer business_card_id) {
        if (business_card_id == null) {
            return "fail";
        }
        Optional<BusinessCard> res = businessCardRepository.findById(business_card_id);
        if (!res.isPresent()) {
            return "fail";
        }
        //二维码生成
        String str = wxClient.generateMpQr("subPage/contacts/sub/bcDetail",business_card_id.toString());
        String last = str.replace("\"", "");
        return last;
    }

    @Override
    @Transactional
    public Map<String, String> dosynchronizationExpert() {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            throw new BadRequestException("登录用户ID未找到");
        }
        UserDto userDto = userService.findById(userId);
        String phone = userDto.getPhone();
        if (phone == null || phone.equals("")) {
            return new HashMap<String, String>(1) {{
                put("status", "unphone");//缺少手机号
            }};
        }
        //从名片预备表里取数据  更新到名片表里
        List<BusinessCardPre> list_businessCardPre = businessCardPreRepository.findByPhone(phone);
        if (list_businessCardPre == null || list_businessCardPre.size() == 0){
            return new HashMap<String, String>(1) {{
                put("status", "unbusinessCard");//未找到名片类
            }};
        }
        BusinessCardPre businessCardPre = list_businessCardPre.get(0);
        //根据预备表手机号、登录用户 查询 名片表是否有该名片
        List<BusinessCard> list_businessCard = businessCardRepository.findByPhoneWithUserId(businessCardPre.getPhone(), userId);
        if (list_businessCard!=null && list_businessCard.size() == 1){
            BusinessCard oldbusinessCard = list_businessCard.get(0);
            oldbusinessCard.setDept(businessCardPre.getDept());
            oldbusinessCard.setAddress(businessCardPre.getAddress());
            oldbusinessCard.setName(businessCardPre.getName());
            oldbusinessCard.setPhone(businessCardPre.getPhone());
            oldbusinessCard.setPost(businessCardPre.getPost());
            oldbusinessCard.setAffiliatedTradeUnion(businessCardPre.getAffiliatedTradeUnion());
            oldbusinessCard.setPhoto(businessCardPre.getPhoto());
            oldbusinessCard.setSuperiorUnit(businessCardPre.getSuperiorUnit());
            businessCardRepository.save(oldbusinessCard);
        }else{
            BusinessCard newbusinessCard = new BusinessCard();
            newbusinessCard.setDept(businessCardPre.getDept());
            newbusinessCard.setAddress(businessCardPre.getAddress());
            newbusinessCard.setName(businessCardPre.getName());
            newbusinessCard.setPhone(businessCardPre.getPhone());
            newbusinessCard.setPost(businessCardPre.getPost());
            newbusinessCard.setAffiliatedTradeUnion(businessCardPre.getAffiliatedTradeUnion());
            newbusinessCard.setPhoto(businessCardPre.getPhoto());
            newbusinessCard.setSuperiorUnit(businessCardPre.getSuperiorUnit());
            newbusinessCard.setUserId(userId);
            businessCardRepository.save(newbusinessCard);
        }
        return new HashMap<String, String>(1) {{
            put("status", "success");//成功
        }};
    }
}